package cn.good.yan.service;

import cn.good.yan.mapper.BillMapper;
import cn.good.yan.pojo.Bill;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.CachePut;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * 演示 - 缓存
 * @author shengren.yan
 * @create 2023-09-20
 */
@Service
// 用来描述该类中所有方法使用的缓存名称，可以不指定，在每个方法上写也可以
@CacheConfig(cacheNames = "Bill")
public class BillServiceImpl {

    @Autowired
    private BillMapper billMapper;

    // 这里 是修饰key 通过该root对象我们可以获取，root是可以省略的  例子：@Cacheable(value="Bill", key="caches[1].name")
    //      methodName	当前方法名	#root.methodName
    //      method	当前方法	#root.method.name
    //      target	当前被调用的对象	#root.target
    //      targetClass	当前被调用的对象的class	#root.targetClass
    //      args	当前方法参数组成的数组	#root.args[0]
    //      caches	当前被调用的方法使用的Cache	#root.caches[0].name


    // 将一个方法的返回值缓存起来 , 默认 key 就是方法的参数，缓存的 value 就是方法的返回值
    // 如果在类上没有加入 @CacheConfig，我们则需要使用 value 来指定缓存名称
    // 参数是多个情况下，需要使用 “:” 来连接 key = "#name+':'+#phone"
    @Cacheable(value = "Bill", key = "#bid")
    public Bill getById(Long bid) {
        List<Bill> byBid = billMapper.findByBid(bid);
        return byBid.get(0);
    }

    // 当数据库中的数据更新后，缓存中的数据也要跟着更新
    // condition 只有当 bill.bid 大于 18 时，才会更新到缓存中, @CachePut(value = "Bill", key = "#bill.bid", condition = "#bill.bid > 18")
    @CachePut(value = "Bill", key = "#bill.bid")
    public Bill updateById(Bill bill) {
        billMapper.updateByBid(bill.getBid());
        List<Bill> byBid = billMapper.findByBid(bill.getBid());
        Bill bill1 = byBid.get(0);
        return bill1;
    }

    // 当数据库中的数据删除后，相关的缓存数据也要自动清除
    // allEntries : 清除全部的缓存  @CacheEvict(value="Bill", allEntries=true)
    // beforeInvocation 方法成功执行之后触发，如果有异常，未有返回值不会清除  @CacheEvict(value="Bill", beforeInvocation=true)
    @CacheEvict(value = "Bill", allEntries = true)
    public void deleteById(Long bid) {
        // 假删除
//        billMapper.deletePByPid(6L);
        billMapper.updateByBid(7L);
    }

}
